package com.fourhats.model;

import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;

@Entity
@Table(name="product")
public class Product extends com.fourhats.model.Entity {

	@Column(name="name")
	private String name;
	
	@Column(name="subtitle")
	private String subtitle;
	
	@Column(name="description")
	private String description;
	
	@Column(name="enable")
	private boolean enable;
	
	@Column(name="price")
	private double price;
	
	@Column(name="quantity")
	private int quantity;
	
	@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
	@JoinColumn(name="productId")
	@OrderBy("isPrincipal DESC")
	private Set<Image> images;
	
	@Column(name="creationDate")
	private Date creationDate;
	
	@Column(name="highlight")
	private boolean highlight;
	
	@Column(name="negotiablePrice")
	private boolean negotiablePrice;
	
	@ManyToOne
    @JoinColumn(name="categoryId")
	private Category category;
	
	@ManyToOne
    @JoinColumn(name="marketId")
	private Market market;
	
	@OneToMany(mappedBy = "product")
    private Set<ProductBuyed> productBuyeds;

	public Product() {
	}
	
	public Product(String name, String subtitle, String description, double price, boolean negotiablePrice, int quantity, Category category){
		this.name = name;
		this.subtitle = subtitle;
		this.description = description;
		if(!negotiablePrice) {
			this.price = price;
		}
		
		this.negotiablePrice = negotiablePrice;
		this.quantity = quantity;
		this.category = category;
		this.enable = true;
		this.creationDate = new Date();
		this.images = new HashSet<Image>();
		//TODO: Esto se hizo inicialmente para que aparezcan todos los productos en la home, hay que cambiarlo mas adelante.
		this.highlight = true;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSubtitle() {
		return subtitle;
	}

	public void setSubtitle(String subtitle) {
		this.subtitle = subtitle;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public boolean isEnable() {
		return enable;
	}

	public void setEnable(boolean enable) {
		this.enable = enable;
	}
	
	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public int getQuantity() {
		return quantity;
	}

	public void setQuantity(int quantity) {
		this.quantity = quantity;
	}
	
	public Set<Image> getImages() {
		return images;
	}

	public void setImages(Set<Image> images) {
		this.images = images;
	}

	public Date getCreationDate() {
		return creationDate;
	}

	public void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}

	public boolean isHighlight() {
		return highlight;
	}

	public void setHighlight(boolean highlight) {
		this.highlight = highlight;
	}

	public boolean isNegotiablePrice() {
		return negotiablePrice;
	}

	public void setNegotiablePrice(boolean negotiablePrice) {
		this.negotiablePrice = negotiablePrice;
	}

	public Category getCategory() {
		return category;
	}

	public void setCategory(Category category) {
		this.category = category;
	}

	public Market getMarket() {
		return market;
	}

	public void setMarket(Market market) {
		this.market = market;
	}

	public Set<ProductBuyed> getProductBuyeds() {
		return productBuyeds;
	}

	public void setProductBuyeds(Set<ProductBuyed> productBuyeds) {
		this.productBuyeds = productBuyeds;
	}

	public void buy() {
		this.setQuantity(this.getQuantity() - 1);
	}
	
	public void setInformation(String name, String subtitle, String description, double price, boolean negotiablePrice, int quantity, Category category){
		this.name = name;
		this.subtitle = subtitle;
		this.description = description;
		if(!negotiablePrice) {
			this.price = price;
		}
		
		this.negotiablePrice = negotiablePrice;
		this.quantity = quantity;
		this.category = category;
	}
	
	@SuppressWarnings({ "rawtypes" })
	public void updateImages(Set<Image> images){
		Set<Image> elementsToDelete = new HashSet<Image>();
		
		for(Iterator i = this.images.iterator(); i.hasNext();){
			Image img = (Image)i.next();
			boolean contains = containsImage(images, img);
			
			if(!contains){
				elementsToDelete.add(img);
			}
		}
		
		this.images.removeAll(elementsToDelete);
		for(Image i : images){
			if(i.getId() == 0){
				this.images.add(new Image(i.getPath(), i.getIsPrincipal()));
			}
		}
	}

	@SuppressWarnings("rawtypes")
	private boolean containsImage(Set<Image> images, Image img) {
		boolean contains = false;
		for(Iterator it = images.iterator(); it.hasNext();){
			if(((Image)it.next()).equals(img)){
				contains = true;
			}
		}
		return contains;
	}
}
